package cloudeval.sample

import cloudeval.spec.*
import cloudeval.spec.metrics.*
import cn.edu.neu.vmmigeval.cloud.entity.RandomUtilizationModel
import cn.edu.neu.vmmigeval.cloud.policy.OneTimeFixMappingDeployment
import cn.edu.neu.vmmigeval.cloud.policy.impl.*
import groovy.transform.BaseScript

@BaseScript ExperimentScript _

DataCenter {

    HostCluster("small-cluster"){
        Hosts(600) {
            cpuFreq 1000
            cpuCores 4
            ram 4000
            disk 1000
            bandwidth 2000
        }
    }

    Broker('small-broker') {
        //TODO configure the Broker.

        // Broker Scale
        // Broker Allocation
        // ...

        def depl = OneTimeFixMappingDeployment.getFromResource("/mapping/small/mapping.txt")

        VM(350) {
            cpuFreq 1000
            ram 500
            bandwidth 150
            disk 150

            deployment depl
        }

        VM(350) {
            cpuFreq 1000
            ram 1000
            bandwidth 150
            disk 150

            deployment depl
        }

        VM(350) {
            cpuFreq 1000
            ram 2000
            bandwidth 150
            disk 150

            deployment depl
        }

        VM(350) {
            cpuFreq 2000
            ram 1000
            bandwidth 150
            disk 150

            deployment depl
        }

        VM(350) {
            cpuFreq 2000
            ram 2000
            bandwidth 150
            disk 150

            deployment depl
        }

        VM(350) {
            cpuFreq 1000
            ram 1000
            bandwidth 150
            disk 150

            deployment depl
        }
    }

    // cloudlets.
    Workload('cpu-intensive') {
        cloudlet(900) {
            def model1 = new RandomUtilizationModel(0.5, 1)
            def model2 = new RandomUtilizationModel(0, 0.3)
            cpu model1
            ram model2
            bandwidth model2
            disk model2
            length 10
        }
    }
}

ScheduleStrategies {

    strategy('DTDT') {
        def m = new MigratedHostPolicyDoubleThreshold()
        migratedHostPolicy  m
        selectionPolicy     new VmSelectionPolicyMU()
        placementPolicy     new VmPlacementPolicyPABFD(m)
    }

    strategy('IMP') {
        def m = new MigratedHostPolicyInterQuartileRange()
//        def m = new MigratedHostPolicyDoubleThreshold()
        migratedHostPolicy  m
        selectionPolicy     new VmSelectionPolicyMinimumMigrationTime()
        selectionPolicy     new VmSelectionPolicyMU()
        placementPolicy     new VmPlacementPolicyPABFD(m)
    }

}

Evaluation {
    def power   = monitor SimplePowerModel
    def pdw     = monitor PDW
    def pdv     = monitor PDV

    def cpuv    = monitor SLA.CPU  >> 0.99
    def ramv    = monitor SLA.RAM  >> 0.99
    def diskv   = monitor SLA.Disk >> 0.99
    def bwv     = monitor SLA.BW   >> 0.99

    metric('Fitness Score') {
        def slav = cpuv + ramv + diskv + bwv
        def fos = pdv * pdw * slav * power
        return fos
    }
}